home *** CD-ROM | disk | FTP | other *** search
- /* amiga/scroll_window.c
- vi:ts=3 sw=3:
- */
-
- /* $Id: scroll_window.c,v 1.3 1995/02/14 16:51:22 espie Exp espie $
- * $Log: scroll_window.c,v $
- * Revision 1.3 1995/02/14 16:51:22 espie
- * *** empty log message ***
- *
- * Revision 1.2 1995/02/13 22:05:42 espie
- * The display takes more space taken into account.
- *
- * Revision 1.1 1995/01/13 13:31:35 espie
- * Initial revision
- *
- * Revision 1.4 1994/01/09 04:49:18 Espie
- * Stupid: forgot that a window font can very well be proportional.
- * It's easier to rely on GfxBase->DefaultFont after all.
- * Uncentralized event handling using event management functions.
- * Handle own's clipping without Layers.
- * Use dynamic colours/masks according to current screen.
- * Added forbid_reopen to avoid dangling window.
- *
- */
-
- /* The line scroller implemented as a window */
-
- #include <assert.h>
-
- #include <intuition/screens.h>
- #include <graphics/text.h>
- #include <graphics/gfxmacros.h>
- #include <proto/intuition.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <graphics/gfxbase.h>
-
- #include "defs.h"
- #include "extern.h"
- #include "amiga/amiga.h"
- #include "prefs.h"
-
- ID("$Id: scroll_window.c,v 1.3 1995/02/14 16:51:22 espie Exp espie $")
-
- LOCAL void init_scroller(void);
- LOCAL void (*INIT)(void) = init_scroller;
- LOCAL int forbid_reopen = FALSE;
- LOCAL void handle_scroller(GENERIC nothing);
-
- XT struct IntuitionBase *IntuitionBase;
- XT struct GfxBase *GfxBase;
-
- LOCAL struct Screen *pubscreen;
-
- /* our window */
- LOCAL struct Window *scroll_win = 0;
- LOCAL struct TextFont *font;
-
-
- /* to build up write masks */
- LOCAL ULONG text, highlight, background;
-
-
- LOCAL void close_scroller()
- {
- if (scroll_win)
- {
- remove_signal_handler(scroll_win->UserPort->mp_SigBit);
- CloseWindow(scroll_win);
- }
- scroll_win = 0; /* and get ready for reopen */
- }
-
- LOCAL void really_close_scroller()
- {
- forbid_reopen = TRUE;
- close_scroller();
- }
-
- /* graphic niceties: draw vertical lines at the right separation points
- * all the way between y1 and the bottom
- */
- LOCAL void separation_lines(int y1)
- {
- int x, xs, i, c;
-
- xs = font->tf_XSize;
-
- SetWrMsk(scroll_win->RPort, background | highlight);
- SetAPen(scroll_win->RPort, highlight);
- x = scroll_win->BorderLeft;
- for (i = 1; i < 5; i++)
- {
- if (i == 3)
- x+= xs;
- else
- x += 14 * xs; /* 14 chars per column */
- c = x - xs/2;
- if (c >= scroll_win->Width - scroll_win->BorderRight -1)
- break;
- Move(scroll_win->RPort, x - xs/2, y1);
- Draw(scroll_win->RPort, x - xs/2, scroll_win->Height - scroll_win->BorderBottom - 1);
- }
- }
-
- LOCAL void init_scroller()
- {
- struct DrawInfo *dr;
-
- at_end(really_close_scroller);
- /* default text, background, etc */
- text = 1;
- background = 0;
- highlight = 7;
- pubscreen = obtain_pubscreen();
- dr = GetScreenDrawInfo(pubscreen);
- if (dr)
- {
- if (dr->dri_Version >= 1) /* for V 2.04 */
- {
- text = dr->dri_Pens[TEXTPEN];
- background = dr->dri_Pens[BACKGROUNDPEN];
- highlight = dr->dri_Pens[SHINEPEN];
- }
- FreeScreenDrawInfo(pubscreen, dr);
- }
- }
-
-
- LOCAL void open_scroller()
- {
- INIT_ONCE;
- font = GfxBase->DefaultFont;
- scroll_win = OpenWindowTags(NULL,
- WA_Title, "Scroll",
- WA_DepthGadget, TRUE,
- WA_SmartRefresh, TRUE,
- WA_DragBar, TRUE,
- WA_SizeGadget, TRUE,
- WA_CloseGadget, TRUE,
- WA_InnerWidth, font->tf_XSize * 60, /* 60 = 14 * 4 + some margin */
- WA_InnerHeight, font->tf_YSize * 15,
- WA_MinWidth, 15 * font->tf_XSize,
- WA_MaxWidth, ~0, /* need some room for the size gadget */
- WA_MinHeight, 2 * pubscreen->WBorTop,
- WA_MaxHeight, ~0,
- WA_AutoAdjust, TRUE,
- WA_NoCareRefresh, TRUE,
- WA_PubScreen, pubscreen,
- WA_IDCMP, IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW,
- TAG_END);
-
- if (!scroll_win)
- end_all(0);
-
- SetFont(scroll_win->RPort, font);
- install_signal_handler(scroll_win->UserPort->mp_SigBit, handle_scroller, 0);
- separation_lines(scroll_win->BorderTop);
- }
-
-
-
- LOCAL void handle_scroller(GENERIC nothing)
- {
- struct IntuiMessage *msg;
- while (scroll_win && (msg = GetMsg(scroll_win->UserPort)))
- switch(msg->Class)
- {
- case IDCMP_NEWSIZE:
- ReplyMsg(msg);
- separation_lines(scroll_win->BorderTop); /* redraw lines where applicable */
- break;
- case IDCMP_SIZEVERIFY:
- ReplyMsg(msg);
- break;
- case IDCMP_CLOSEWINDOW:
- ReplyMsg(msg);
- close_scroller();
- set_pref_scalar(PREF_SHOW, FALSE);
- break;
- default:
- ReplyMsg(msg);
- }
- }
-
- void add_scroller(char *s)
- {
- int max_length;
-
- if (forbid_reopen)
- return;
- if (!scroll_win)
- open_scroller();
-
- /* critical section for size changes */
- ModifyIDCMP(scroll_win, scroll_win->IDCMPFlags | IDCMP_SIZEVERIFY);
- handle_scroller(0); /* handle size problems first */
-
- if (!scroll_win) /* window may have closed on us... */
- return;
-
- /* add the characters */
- SetDrMd(scroll_win->RPort, JAM1);
- SetWrMsk(scroll_win->RPort, background | text);
- SetAPen(scroll_win->RPort, text);
- Move(scroll_win->RPort, scroll_win->BorderLeft,
- scroll_win->Height - scroll_win->BorderBottom
- - font->tf_YSize + font->tf_Baseline);
- max_length = scroll_win->Width - scroll_win->BorderLeft - scroll_win->BorderRight;
- max_length /= font->tf_XSize;
- if (max_length > 14 * 4)
- max_length = 14 * 4; /* line length = 14 * 4 */
- Text(scroll_win->RPort, s, max_length);
-
- /* add the separation lines */
- separation_lines(scroll_win->Height - scroll_win->BorderBottom
- - font->tf_YSize);
-
- /* and scroll *JUST* the characters */
- SetWrMsk(scroll_win->RPort, 1);
- ScrollRaster(scroll_win->RPort, 0, font->tf_YSize,
- scroll_win->BorderLeft, scroll_win->BorderTop,
- scroll_win->Width - scroll_win->BorderRight - 1,
- scroll_win->Height - scroll_win->BorderBottom - 1);
-
- /* end of critical section: allow resize again */
- ModifyIDCMP(scroll_win, scroll_win->IDCMPFlags & ~IDCMP_SIZEVERIFY);
- handle_scroller(0);
- }
-